package com.heima.user.service.impl;

import com.heima.commom.constants.user.UserRelationConstants;
import com.heima.common.exception.CustException;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.dtos.UserRelationDTO;
import com.heima.model.user.pojos.ApUser;
import com.heima.user.service.ApUserRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class ApUserRelationServiceImpl implements ApUserRelationService {

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 关注或取关
     * @param dto
     * @return
     */
    @Override
    public ResponseResult follow(UserRelationDTO dto) {
        //判断要关注的文章作者的用户id
        if(dto.getArticleId() == null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"当前文章作者的userId为空");
        }
        //判断关注的操作字段是否为空 或不等于0 或不等于1
        Integer operation = dto.getOperation().intValue();
        if((operation != 0 && operation !=1) || operation == null){
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //获取当前用户的id 如果是作者自己的话 不能自己关注自己
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null){
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        //如果当前线程中登录的用户 和当前文章中作者的用户id 一致的话就是一个人
        Integer authorApUserId = dto.getAuthorApUserId();
        Integer userId = user.getId();
        if(authorApUserId.equals(userId)){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"自己不能关注自己");
        }
        // 当前登录的用户A为关注者  当前文章的作者id B为被关注者  A关注了B 那么A就是B的粉丝
        // 校验之前有没有关注过
        Double score = redisTemplate.opsForZSet().score(UserRelationConstants.FOLLOW_LIST + userId, String.valueOf(authorApUserId));
        //dto 中如果 传过来的参数 为0的话 就是要关注的操作  为1 的话就是取消关注
        //如果 传过来的参数 为0 且 redis中的score 不为空的话 那么就是已经关注过了 所以不能再关注
        if(score != null && operation.intValue() == 0){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"已经关注过了 不能再关注了");
        }

        try {
            //根据传参不同操作不同 为0 是关注  1是 取关
            if(operation == 0){
                //用户关注作者  三个参数  key 为当前用户的id  value 为关注的作者id  还有时间戳
                redisTemplate.opsForZSet()
                        .add(UserRelationConstants.FOLLOW_LIST + userId,String.valueOf(authorApUserId),System.currentTimeMillis());
                //作者的粉丝   key为作者id  value 为 粉丝id也就是当前操作的用户id 第三个参数时间戳
                redisTemplate.opsForZSet()
                        .add(UserRelationConstants.FANS_LIST + authorApUserId,String.valueOf(userId),System.currentTimeMillis());
            }else {
                // 如果参数不为0 的话就是取消关注  删除对应的关系 即可
                //删除当前用户关注的作者信息
                redisTemplate.opsForZSet()
                        .remove(UserRelationConstants.FOLLOW_LIST + userId,String.valueOf(authorApUserId));
                //从作者的粉丝中删除此用户
                redisTemplate.opsForZSet()
                        .remove(UserRelationConstants.FANS_LIST + authorApUserId,String.valueOf(userId));
            }
        } catch (Exception e) {
            e.printStackTrace();
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"redis 关注或取关 出错了");
        }
        return ResponseResult.okResult();
    }
}
